using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Web;
using System.Globalization;
using System.Reflection;

namespace Soyuz5.Utility.Web
{
    public class WebNavigation
    {
        NameValueCollection _query;
        const string DATE_TIME_FORMAT = "yyyy-MM-dd";

        public WebNavigation(string queryString){
            _query = HttpUtility.ParseQueryString(queryString);
        }

        public WebNavigation()
        {
            Reset();
        }

        public void Reset()
        {
            _query = HttpUtility.ParseQueryString(HttpContext.Current.Request.Url.Query);
        }

        public string GetValue(string key)
        {
            return _query[key.ToLower()];
        }

        public void SetValue(string key, string value)
        {
            if (!string.IsNullOrEmpty(value))
                _query[key.ToLower()] = value;
            else Remove(key);
        }

        public void SetValue(string key, int value)
        {
            if (value != 0)
                _query[key.ToLower()] = value.ToString();
            else Remove(key);
        }

        public void SetValue(string key, System.DateTime? value)
        {
            if (value.HasValue && value.Value != System.DateTime.MinValue)
                _query[key.ToLower()] = value.Value.ToString(DATE_TIME_FORMAT);
            else Remove(key);
        }

        public void Remove(string key)
        {
            _query.Remove(key.ToLower());
        }

        public int GetValue(string key, int defaultValue)
        {
            return parseInt(_query[key.ToLower()], defaultValue);
        }

        public DateTime? GetValue(string key, DateTime? defaultValue)
        {
            return parseDate(_query[key.ToLower()], defaultValue);
        }

        int parseInt(string value, int defaultValue){

            if (value == null)
                return defaultValue;

            int intCruiseLine = 0;
            if (Int32.TryParse(value, out intCruiseLine))
            {
                return intCruiseLine;
            }
            return defaultValue;
        }

        DateTime? parseDate(string value, DateTime? defaultValue)
        {
            if (string.IsNullOrEmpty(value))
                return defaultValue;

            DateTime result = DateTime.Now;
            if (DateTime.TryParseExact(value, DATE_TIME_FORMAT, CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out result))
            {
                return result;
            }
            return defaultValue;
        }

        public override string ToString()
        {
            return HttpContext.Current.Request.Url.LocalPath + "?" + _query.ToString();
        }

        public void Redirect()
        {
            Redirect(HttpContext.Current.Request.Url.LocalPath);
        }

        public void Redirect(string url)
        {
            HttpContext.Current.Response.Redirect(url + "?" + _query.ToString());
        }

        public void Clear()
        {
            _query.Clear();
        }

        public void FillObject(object obj)
        {
            PropertyInfo[] properties = obj.GetType().GetProperties();
            foreach (PropertyInfo pi in properties)
            {
                if (_query[pi.Name.ToLower()] != null)
                {
                    if (pi.PropertyType.Equals(typeof(string)))
                    {
                        pi.SetValue(obj, GetValue(pi.Name), null);
                    }
                    if (pi.PropertyType.Equals(typeof(int)))
                    {
                        pi.SetValue(obj, GetValue(pi.Name, 0), null);
                    }
                    if (pi.PropertyType.Equals(typeof(DateTime?)))
                    {
                        pi.SetValue(obj, GetValue(pi.Name, (DateTime?)null), null);
                    }
                }
            }
        }

        public void LoadFromObject(object obj)
        {
            PropertyInfo[] properties = obj.GetType().GetProperties();
            foreach (PropertyInfo pi in properties)
            {
                if (_query[pi.Name.ToLower()] != null)
                {
                    if (pi.PropertyType.Equals(typeof(string)))
                    {
                        string data = (string)pi.GetValue(obj, null);
                        SetValue(pi.Name, data);
                    }
                    if (pi.PropertyType.Equals(typeof(int)))
                    {
                        int data = (int)pi.GetValue(obj, null);
                        SetValue(pi.Name, data);
                    }
                    if (pi.PropertyType.Equals(typeof(DateTime?)))
                    {
                        DateTime? data = (DateTime?)pi.GetValue(obj, null);
                        SetValue(pi.Name, data);
                    }
                }
            }
        }
    }
}
